package handlers

import (
	"encoding/json"
	"fmt"
	"math"
	"net/http"
	"strings"
	"werewolf/core"
)

func JudgeHandler(w http.ResponseWriter, r *http.Request) {          //   评价当局游戏的胜负结果

	if r.Method != http.MethodGet {
		http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
		return
	}

	handle, err := core.Connection()
	if err!= nil {
		fmt.Println(err)
		return
	}
	defer handle.Close()

	room := r.URL.Query().Get("room")
	role := r.URL.Query().Get("role")
	if room == "" {
		http.Error(w, "Invalid room name", http.StatusBadRequest)
		return
	}

	tx, err := handle.Begin()
	if err!= nil {
		http.Error(w, "Failed to begin transaction", http.StatusInternalServerError)
		return
	}

	var death1, death2, death3, guardId int
	err = handle.QueryRow("SELECT death1,death2,death3,`g-guard` FROM running WHERE RmNo = ?", room).Scan(&death1, &death2, &death3, &guardId)
	if err!= nil {
		http.Error(w, "Error getting death count: " +err.Error(), http.StatusInternalServerError)
		return
	}

	isSurvived := checkGuardSurvived(room)

	guardId = int(math.Abs(float64(guardId)))

	if death1 != 0 {
		if (death1 != guardId || !isSurvived) && !checkDevil(fmt.Sprintf("%d", death1), room) {
			_, err = tx.Exec("UPDATE player SET Survival = 0 WHERE RmNo = ? AND No = ?", room, death1)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating player: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}else{
			_, err = tx.Exec("UPDATE running SET death1 = 0 WHERE RmNo = ?", room)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating running: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}
	}
	if death2 != 0  {
		if !checkDevil(fmt.Sprintf("%d", death2), room){
			_, err = tx.Exec("UPDATE player SET Survival = 0 WHERE RmNo = ? AND No = ?", room, death2)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating player: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}else{
			_, err = tx.Exec("UPDATE running SET death2 = 0 WHERE RmNo = ?", room)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating running: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}
	}
	if death3 != 0 {
		if (death1 != guardId || !isSurvived) && !checkDevil(fmt.Sprintf("%d", death3), room) {
			_, err = tx.Exec("UPDATE player SET Survival = 0 WHERE RmNo = ? AND No = ?", room, death3)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating player: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}else{
			_, err = tx.Exec("UPDATE running SET death3 = 0 WHERE RmNo = ?", room)
			if err!= nil {
				_ = tx.Rollback()
				http.Error(w, "Error updating running: " +err.Error(), http.StatusInternalServerError)
				return
			}
		}
	}

	if role != "none"{	
		updateString := fmt.Sprintf("UPDATE running SET `%s` = -`%s` , boomable = 1 WHERE RmNo = %s", role, role, room)
		_, err = tx.Exec(updateString)
		if err!= nil {
			_ = tx.Rollback()
			http.Error(w, "Error updating running: " +err.Error(), http.StatusInternalServerError)
			return
		}
	}
	
	var rolelist []string
	JSONdata := r.URL.Query().Get("rolelist")
	err = json.Unmarshal([]byte(JSONdata), &rolelist)
	if err != nil {
		http.Error(w, "Error unmarshalling rolelist: " +err.Error(), http.StatusBadRequest)
		return
	}

	rows, err := tx.Query("SELECT Role, Survival FROM player WHERE RmNo = ?", room)
	if err!= nil {
		_ = tx.Rollback()
		http.Error(w, "Error starting transaction: " +err.Error(), http.StatusInternalServerError)
		return
	}
	defer rows.Close()

	w_survival := 0 
	f_survival := 0

	for rows.Next() {
		var index, survival int
		err := rows.Scan(&index, &survival)
		if err!= nil {
			_ = tx.Rollback()
			http.Error(w, "Error scanning row: " +err.Error(), http.StatusInternalServerError)
			return
		}
		if survival == 1 {
			if rolelist[index-1][0] == 'w' {
				w_survival++
			}else{
				f_survival++
			}
		}
	}

	if err := tx.Commit(); err!= nil {
		http.Error(w, "Failed to commit transaction: "+err.Error(), http.StatusInternalServerError)
		return
	}

	if w_survival >= f_survival {
		fmt.Fprintf(w, "wolf")
	}else if w_survival <= 0 {
		fmt.Fprintf(w, "folk")
	}else {
		fmt.Fprintf(w, "continue")
	}

}

func checkGuardSurvived(room string) bool{
	handle, err := core.Connection()
	if err != nil {
		fmt.Println("Connection failed: " + err.Error())
		return false
	}
	defer handle.Close()
	var roles string
	var ms string
	err = handle.QueryRow("SELECT Role FROM Game WHERE RmNo=?", room).Scan(&roles)
	if err != nil {
		fmt.Println("Error fetching game info: " + err.Error())
		return false
	}
	roleList := strings.Split(roles, ";")
	index := 0
	for index = 0; index < len(roleList); index++ {
		if roleList[index] == "g-guard" {
			break
		}
	}

	if index >= len(roleList) {
		return false
	}else{
		err = handle.QueryRow("SELECT survival FROM player WHERE RmNo = ? AND role = ?", room, index + 1).Scan(&ms)
		if err != nil {
			fmt.Println("Error fetching player info: " + err.Error())
			return false
		}
		if ms == "1"{
			return true
		}
	}

	return false
}
	